/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.openbookformat.project.newprojectwizard;

import com.smallutil.io.FileRW;
import com.smallutil.io.WebUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import org.htmlparser.util.ParserException;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.netbeans.api.progress.ProgressUtils;
import org.openbookformat.project.Chapter;
import org.openbookformat.project.HeadingPointer;
import org.openbookformat.tags.PagebreakTag;
import org.openbookformat.tags.WarningTag;
import org.openide.WizardDescriptor;
import org.openide.execution.ExecutionEngine;
import org.openide.util.Exceptions;
import org.openide.windows.IOProvider;
import org.openide.windows.InputOutput;

/**
 *
 * @author matamh0a
 */
public class OBFProjectCreator {
    public static boolean create(final Properties wd) {
        System.out.println("Start Creating Project ...");
        
        ExecutionEngine engine = ExecutionEngine.getDefault();
        engine.execute("Creating OBF Project ...", new Runnable() {

            @Override
            public void run() {
                String NL = "\n";
                InputOutput inOut = IOProvider.getDefault().getIO("Creating OBF Project ...", null);
                ProgressHandle handle = ProgressHandleFactory.createHandle(
                "Creating OBF Project ...");
                boolean success = false;
                handle.start();
                
                //creating project directory
                String projDir = wd.getProperty(NewOBFProjectVisualPanel1.PROP_PROJECTFOLDER);
                System.out.print("- Creating project directory... ");
                success = (new File(projDir)).mkdirs();
                System.out.println(success?"done.":"fail.");
                System.out.print("- Creating project source directory... ");
                success = (new File(projDir + File.separator + "src")).mkdirs();
                System.out.println(success?"done.":"fail.");
//                if(!success) {
//                    System.out.println("Could not create project directory " + projDir + ".");
//                    handle.finish();
//                    return;
//                }
                
                
                //processing files
                StringBuilder buff = new StringBuilder();
                ArrayList<HeadingPointer> pointers = new ArrayList<HeadingPointer>();
                ArrayList<String> subpages = (ArrayList<String>) wd.get(
                        NewOBFProjectVisualPanel2.PROP_SUBPAGES);
                String encoding = (String) wd.get(NewOBFProjectWizardPanel2.PROP_ENCODING);
                
                String pagePattern = (String) wd.get(NewOBFProjectVisualPanel3.PROP_PAGE_PATTERN);
                boolean userPagePattern = (Boolean)wd.get(NewOBFProjectVisualPanel3.PROP_USE_PAGE_GROUP);
                int pageGroup = (Integer) wd.get(NewOBFProjectVisualPanel3.PROP_PAGE_GROUP);
                
                String headingsPattern = (String) wd.get(NewOBFProjectVisualPanel3.PROP_HEADINGS_PATTERN);
                boolean userheadingsPattern = (Boolean)wd.get(NewOBFProjectVisualPanel3.PROP_USE_HEADINGS_GROUP);
                int headingsGroup = (Integer) wd.get(NewOBFProjectVisualPanel3.PROP_HEADINGS_GROUP);
                
                int numOfChpt = (Integer) wd.get(NewOBFProjectVisualPanel2.PROP_NUMBEROFCHAPTERS);
                if(numOfChpt > subpages.size()) {
                    numOfChpt = subpages.size();
                }
                System.out.println("- Processing input files...");
                System.out.println("  + Compiling " + subpages.size() 
                        + " file[s] into " + numOfChpt + " chapters...");
                int spIdx = 0;
                int spCount = 0;
                String contents = null;
                String chptPath = null;
                int curFirstPage = -1;
                int curLastPage = -1;
                int nextFirstPage = -1;
                int nextLastPage = -1;
                Pattern pattern = null;
                Matcher matcher = null;
                int[] r = {-1, -1};
                for(int i = 0; i < numOfChpt; i++) {
                    try {
                        spCount = subpages.size() / numOfChpt 
                                + ((i+1) <= subpages.size() % numOfChpt? 1 : 0);
                        System.out.println("  + Compiling[" + (i+1) + "/" 
                                + numOfChpt + "]: Chapter " + (i+1) + " - " +
                                spCount + " subpage[s].");
                        
                        buff.setLength(0);
                        buff.append("<?xml version=\"1.0\" encoding=\"").
                                append(encoding).append("\"?>").append(NL);
                        buff.append("<book-part index='").append(i+1).append("'>").append(NL);
                        
                        for(int j = 0; j < spCount; j++) {
                            try {
                                System.out.println("    * Processing[" + (spIdx+1) + "/" 
                                        + subpages.size() + "]:" + subpages.get(spIdx));
                                //processing each link
                                contents = WebUtil.getHttp(subpages.get(spIdx), encoding);
                                
                                if(spIdx + 1 < subpages.size()) {
                                    
                                    //find first and last page [current link]
                                    if (nextFirstPage == -1) {
                                        r = NewOBFProjectUtil.getFirstnLastPage(
                                                subpages.get(spIdx), encoding,
                                                pagePattern, userPagePattern, pageGroup);
                                        curFirstPage = r[0];
                                        curLastPage = r[1];
                                    } else {
                                        curFirstPage = nextFirstPage;
                                        curLastPage = nextLastPage;
                                    }

                                    //find first and last page [next link]
                                    r = NewOBFProjectUtil.getFirstnLastPage(
                                            subpages.get(spIdx + 1), encoding,
                                            pagePattern, userPagePattern, pageGroup);
                                    nextFirstPage = r[0];
                                    nextLastPage = r[1];
                                    if (nextFirstPage == -1) {
                                        System.err.println("      - Redetecting "
                                                + "page break pattern for next file.");
                                        r = NewOBFProjectUtil.getFirstnLastPage(
                                                subpages.get(spIdx + 1), encoding,
                                                NewOBFProjectUtil.getPagePattern(
                                                NewOBFProjectUtil.html2Text(
                                                WebUtil.getHttp(subpages.get(
                                                spIdx + 1), encoding))),
                                                userPagePattern, pageGroup);
                                        nextFirstPage = r[0];
                                        nextLastPage = r[1];
                                    }
                                }
                                System.out.println("      - First Page --> " + curFirstPage
                                        + ", Last Page --> " + curLastPage);
                                
                                buff.append(NewOBFProjectUtil.html2Text(contents));
                                if(spIdx + 1 < subpages.size() 
                                        && nextFirstPage - curLastPage > 1) {
                                    buff.append("\n" + (new PagebreakTag(
                                        nextFirstPage -1)).toString());
                                } 
                                
                                if(spIdx + 1 < subpages.size() 
                                        && curLastPage - curFirstPage < 0) {
                                    buff.append("\n" + (new WarningTag(""
                                            + "Check page numbers")).toString());
                                } 
                               
                                //processing headings
                                pointers.addAll(NewOBFProjectUtil.getHeadings(contents,
                                        new Chapter("Chapter" + ((i+1)<9?"0":"") + (i+1)), 
                                        headingsPattern , 1, headingsGroup, 3));
                                
                                spIdx++;
                            } catch (IOException ex) {
                                Exceptions.printStackTrace(ex);
                            } catch (ParserException ex) {
                                Exceptions.printStackTrace(ex);
                            }
                        }                    
                        buff.append("</book-part>");
                        
                        chptPath = projDir + File.separator + "src" + 
                                File.separator + "Chapter" + ((i+1)<9?"0":"") 
                                + (i+1) + ".obf";
                        System.out.println("  + Saving " + chptPath + " ..." );
                        FileRW.save(chptPath,  buff.toString(), encoding);
                    } catch (IOException ex) {
                        Exceptions.printStackTrace(ex);
                    }
                }
                
                
                //obfproject.xml 
                System.out.print("- Creating project file obfproject.xml...");
                buff.setLength(0);
                buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(NL);
                buff.append("<project-prop>").append(NL);
                buff.append("\t<chapters>").append(NL);
                for(int i = 0; i < numOfChpt; i++) {
                    buff.append("\t\t<chapter>Chapter").append((i+1)<9?"0":"")
                            .append(i+1).append("</chapter>").append(NL);
                }
                buff.append("\t</chapters>").append(NL);
                buff.append("</project-prop>").append(NL);
                try {
                    FileRW.save(projDir + File.separator + "obfproject.xml",  
                            buff.toString(), "utf-8");
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }
                System.out.println(" done.");
                
                
                //headings.properties
                System.out.print("- Creating headings file headings.properties ...");
                SortedProperties headings = new SortedProperties();
                //appending headings
                String ptrIdx = null;
                String heading = null;
                for (int i = 0; i < pointers.size(); i++) {
//                    System.out.println("Processing: " + i );
                    heading =  NewOBFProjectUtil.html2Text(pointers.get(i).getHeading());
                    if(heading.trim().length() == 0) {
                        pointers.remove(i);
                        i--;
                        System.out.println("daaaaaaaa");
                        continue;
                    }
                    ptrIdx = ((i+1)<99?"0":"") + ((i+1)<9?"0":"") + i;
                    headings.put("idx_" + ptrIdx + "_chapter",
                            pointers.get(i).getChapter().getTitle());
                    headings.put("idx_" + ptrIdx + "_offset",
                            pointers.get(i).getOffset() + "");
                    headings.put("idx_" + ptrIdx + "_level",
                            pointers.get(i).getLevel()+ "");
                    headings.put("idx_" + ptrIdx + "_heading",
                           heading);
                }
                headings.put("heading_count", pointers.size() +"");
                try {
                    headings.store(new FileOutputStream(
                            projDir + File.separator + "headings.properties"), null);
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }
                System.out.println(" done.");
                
                
                handle.finish();
            }
            
        }, InputOutput.NULL);
        
        try {
            Thread.sleep(8 * 1000);
        } catch (InterruptedException ex) {
            Exceptions.printStackTrace(ex);
        }
        return true;
    }
    
    public static void main(String[] args) {
        try {
            String projName = "سيد المرسلين - ج1";
            Properties wd = new Properties();
            
            wd.put(NewOBFProjectVisualPanel1.PROP_PROJECTNAME,
                    projName);
            wd.put(NewOBFProjectVisualPanel1.PROP_PROJECTFOLDER, 
                    "D:\\data\\tmp\\" + projName);
            wd.put(NewOBFProjectVisualPanel1.PROP_WEBINDEX, 
                    "D:\\Users\\matamh0a\\Downloads\\sayd1\\sayd1\\index.htm");
            
            
            String webIndex = (String) wd.getProperty(
                        NewOBFProjectVisualPanel1.PROP_WEBINDEX);
             
            //find subpages.
            String encoding = NewOBFProjectUtil.getPageCharset(webIndex);
            String base = webIndex;
            int idx = webIndex.lastIndexOf("/") == -1 ? webIndex.length() : webIndex.lastIndexOf("/");
            if (idx == webIndex.length()) {
                idx = webIndex.lastIndexOf("\\") == -1 ? webIndex.length() : webIndex.lastIndexOf("\\");
            }
            base = webIndex.substring(0, idx);
            ArrayList<String> links = NewOBFProjectUtil.getLinks(
                    WebUtil.getHttp(webIndex, encoding), base);
            
            wd.put(NewOBFProjectVisualPanel2.PROP_HEADINGFROMSUBPAGES, 
                    true);
            wd.put(NewOBFProjectVisualPanel2.PROP_NUMBEROFCHAPTERS, 
                    5);
            wd.put(NewOBFProjectVisualPanel2.PROP_SUBPAGES, 
                    links);
            wd.put(NewOBFProjectWizardPanel2.PROP_ENCODING, encoding);
            
            
            wd.put(NewOBFProjectVisualPanel3.PROP_PAGE_PATTERN,
                "\\s*\\Q{\\E\\s*(\\d+)\\s*\\Q}\\E\\s*");
            wd.put(NewOBFProjectVisualPanel3.PROP_USE_PAGE_GROUP,
                true);
            wd.put(NewOBFProjectVisualPanel3.PROP_PAGE_GROUP,
                1);
        
            wd.put(NewOBFProjectVisualPanel3.PROP_HEADINGS_PATTERN,
                "(?i)<h(\\d)>([^{\\(].*?)</h\\1>");
            wd.put(NewOBFProjectVisualPanel3.PROP_USE_HEADINGS_GROUP,
                true);
            wd.put(NewOBFProjectVisualPanel3.PROP_HEADINGS_GROUP,
                2);
            
        
            create(wd);
            
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        } catch (ParserException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
}
